//
//  SWNotificationCenter.swift
//  Basic
//
//  Created by linhan on 16/6/4.
//  Copyright © 2016年 linhan. All rights reserved.
//

import Foundation
class SWNotificationCenter: NSObject
{
    class func post(name aName: NSNotification.Name, object anObject: Any? = nil, userInfo aUserInfo: [AnyHashable : Any]? = nil, queue: OperationQueue? = nil)
    {
        //如未指定具体队列，则在主队列中发送
        (queue ?? OperationQueue.main).addOperation({
            NotificationCenter.default.post(name: aName, object: anObject, userInfo: aUserInfo)
        })
    }
    
    class func removeObserver(_ observer: AnyHashable)
    {
        let hash:Int = observer.hashValue
        if let observers = targets[hash]
        {
            for (_, obs) in observers
            {
                NotificationCenter.default.removeObserver(obs)
            }
            targets.removeValue(forKey: hash)
        }
        else
        {
            NotificationCenter.default.removeObserver(observer)
        }
    }
    
    class func removeObserver(_ observer: AnyHashable, name aName: String?, object anObject: Any?)
    {
        let hash:Int = observer.hashValue
        if var observers = targets[observer.hashValue]
        {
            if let name = aName, name != ""
            {
                if let obs = observers[name]
                {
                    NotificationCenter.default.removeObserver(obs)
                    observers.removeValue(forKey: name)
                    targets[hash] = observers
                }
            }
            else
            {
                removeObserver(observer)
            }
        }
        else
        {
            NotificationCenter.default.removeObserver(observer)
        }
    }
    
    class func addObserver(_ observer: AnyHashable, selector aSelector: Selector, name aName: NSNotification.Name, object anObject: Any?)
    {
        let hash:Int = observer.hashValue
        var observers:[String:SWWeakObserver] = targets[hash] ?? [:]
        let obs = observers[aName.rawValue] ?? SWWeakObserver()
        obs.target = observer as? AnyObject
        obs.selector = aSelector
        observers[aName.rawValue] = obs
        targets[hash] = observers
        
        NotificationCenter.default.addObserver(obs, selector: #selector(SWWeakObserver.selectorHandler(_:)), name: aName, object: anObject)
    }
    
    class func addObserverOnMainThread(name: NSNotification.Name, usingBlock block: @escaping (Notification) -> Void)
    {
        NotificationCenter.default.addObserver(forName: name, object: nil, queue: OperationQueue.main, using: block)
    }
    
    static private var targets:[Int:[String:SWWeakObserver]] = [:]
}

private class SWWeakObserver:NSObject
{
    weak var target:AnyObject?
    var selector:Selector?
    
    deinit
    {
        //print("DEINIT SWWeakObserver")
    }
    
    @objc func selectorHandler(_ notification:NSNotification)
    {
        //print("selectorHandler", notification.name)
        if let target = target,
           let selector = selector
        {
            target.performSelector(onMainThread: selector, with: notification, waitUntilDone: false)
            //target.performSelector(selector, withObject: notification)
        }
    }
}

